package com.link2room.rodimus.facade.impl;

import com.link2room.blaster.constant.MsgConstant;
import com.link2room.blaster.util.MessageFlatPad;
import com.link2room.common.constant.BaseConstant;
import com.link2room.common.dto.result.base.MemberSessionDto;
import com.link2room.common.dto.threadlocal.ApiThreadLocal;
import com.link2room.common.enums.BaseSysExceptionEnum;
import com.link2room.common.exception.SysException;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.*;
import com.link2room.enums.exception.RodimusSysExceptionEnum;
import com.link2room.jetfire.constant.ReservationConstant;
import com.link2room.jetfire.dto.param.base.ReservationParamDto;
import com.link2room.jetfire.dto.result.base.ReservationBaseDto;
import com.link2room.jetfire.dto.result.base.ReservationDto;
import com.link2room.optimus.constant.BaseRateplanConstant;
import com.link2room.rodimus.constant.InComingDetailConstant;
import com.link2room.rodimus.constant.SaleMemberConstant;
import com.link2room.rodimus.dto.param.api.SalesmanApiParamDto;
import com.link2room.rodimus.dto.param.inside.SalesmanAwardMemberInsideParamDto;
import com.link2room.rodimus.dto.param.inside.SalesmanInComeDetailInsideParamDto;
import com.link2room.rodimus.dto.result.base.SalesmanBaseInfoDto;
import com.link2room.rodimus.dto.result.base.SalesmanIncomeDetailDto;
import com.link2room.rodimus.dto.result.base.SalesmanMemberDto;
import com.link2room.rodimus.entity.SalesmanBase;
import com.link2room.rodimus.entity.SalesmanIncomeDetail;
import com.link2room.rodimus.entity.SalesmanIncomingdetailLogEntity;
import com.link2room.rodimus.entity.SalesmanMember;
import com.link2room.rodimus.facade.ISalesmanApiFacadeService;
import com.link2room.rodimus.feign.jetfire.ReservationsFeignService;
import com.link2room.rodimus.service.ISalesmanRewardsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

import static com.link2room.enums.exception.RodimusSysExceptionEnum.MOBILE_EXIT;
import static com.link2room.enums.exception.RodimusSysExceptionEnum.SYNC_SALESMAN_AWARD_ERROR;


/**
 * Created by VegetaKo on 2016/9/21.
 */
@Service("salesmanFacadeService")
public class SalesmanApiFacadeServiceImpl implements ISalesmanApiFacadeService {
    @Resource
    private ICommonService commonService;

    @Resource
    private MessageFlatPad messageFlatPad;

    @Autowired
    private RedisLockRegistry syncSalesmanIncomingDetailLock;

    @Resource
    private ReservationsFeignService reservationsFeignService;

    @Resource
    private ISalesmanRewardsService salesmanRewardsService;

    @Override
    public void saveSalesman(SalesmanApiParamDto salesmanApiParamDto) throws Exception {
        String organizationCode = salesmanApiParamDto.getOrganizationCode();
        L2RAssert.stringBlank(organizationCode, "[organizationCode] is null.");
        String lhotelGroupCode = salesmanApiParamDto.getLhotelGroupCode();
        L2RAssert.stringBlank(lhotelGroupCode, "[lhotelGroupCode] is null.");
        String mobile = salesmanApiParamDto.getMobile();
        L2RAssert.stringBlank(mobile, "[mobile] is null.");
        String salesmanName = salesmanApiParamDto.getSalesmanName();
        L2RAssert.stringBlank(salesmanName, "[salesmanName] is null.");
        L2RAssert.isTrue(hasMobile(mobile), new SysException(MOBILE_EXIT, "分销员手机号重复."));

        SalesmanBase salesmanBase = new SalesmanBase();
        salesmanBase.setOrganizationCode(organizationCode);
        salesmanBase.setSalesmanNo("");
        salesmanBase.setSalesmanName(salesmanName);
        salesmanBase.setLhotelGroupCode(lhotelGroupCode);
        salesmanBase.setLhotelCode(organizationCode);
        salesmanBase.setMobile(mobile);
        if (StringUtil.isNotBlank(salesmanApiParamDto.getTicket())) {
            MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();
            salesmanBase.setSalesmanWxopenid(memberSessionDto.getOpenid());
            salesmanBase.setSalesmanNo(memberSessionDto.getOpenid());
        }
        salesmanBase.setRewards(BigDecimal.ZERO);
        salesmanBase.setSta("R");
        commonService.save(salesmanBase);
    }

    private boolean hasMobile(String mobile) throws Exception {
        SalesmanBase find = new SalesmanBase();
        find.setMobile(mobile);
        long count = commonService.getCountAllEQ(SalesmanBase.class, find, null);
        return 0 > count;
    }

    @Override
    public void modifySalesman(SalesmanApiParamDto salesmanApiParamDto) throws Exception {
        if (StringUtil.isNotBlank(salesmanApiParamDto.getTicket())) {
            MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();
            SalesmanBase salesmanBase = new SalesmanBase();
            salesmanBase.setSalesmanWxopenid(memberSessionDto.getOpenid());
            salesmanBase = commonService.findOneEQ(SalesmanBase.class, salesmanBase);

            salesmanBase.setSta("R");
            commonService.merge(salesmanBase);
        } else {
            throw new SysException(RodimusSysExceptionEnum.SALESMAN_NOT_EXIT);
        }
    }


    @Override
    public SalesmanBase getSalesman(SalesmanApiParamDto salesmanApiParamDto) throws Exception {
        if (StringUtil.isNotBlank(salesmanApiParamDto.getTicket())) {
            MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();
            SalesmanBase salesmanBase = new SalesmanBase();
            salesmanBase.setSalesmanWxopenid(memberSessionDto.getOpenid());
            salesmanBase = commonService.findOneEQ(SalesmanBase.class, salesmanBase);
            return salesmanBase;
        } else {
            throw new SysException(RodimusSysExceptionEnum.SALESMAN_NOT_EXIT);
        }
    }

    @Override
    public SalesmanBaseInfoDto getCurrentSalesmanBaseInfo(SalesmanApiParamDto salesmanApiParamDto) throws Exception {
        MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();
        String mobile = memberSessionDto.getMobile();
        SalesmanBase find = new SalesmanBase();
        find.setMobile(mobile);
        find.setLhotelGroupCode(salesmanApiParamDto.getLhotelGroupCode());
        SalesmanBase salesmanBase = commonService.findOneEQ(SalesmanBase.class, find);
        if (salesmanBase != null) {
            return ClassConverUtil.copyProperties(salesmanBase, SalesmanBaseInfoDto.class);
        } else {
            return null;
        }
    }

    @Override
    public QueryResult<SalesmanIncomeDetailDto> getSalesmanIncomeDetails(SalesmanApiParamDto salesmanApiParamDto) throws Exception {
        if (StringUtil.isNotBlank(salesmanApiParamDto.getTicket())) {
            MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();

            SalesmanBase salesmanBase = new SalesmanBase();
            salesmanBase.setSalesmanWxopenid(memberSessionDto.getOpenid());
            salesmanBase = commonService.findOneEQ(SalesmanBase.class, salesmanBase);
            SalesmanIncomeDetail salesmanIncomeDetail = new SalesmanIncomeDetail();
            salesmanIncomeDetail.setSalesmanNo(salesmanBase.getSalesmanNo());
            salesmanIncomeDetail.setAwardSta(salesmanApiParamDto.getAwardSta());
            QueryResult<SalesmanIncomeDetail> salesmanIncomeDetailQueryResult = commonService.findAllEQ(SalesmanIncomeDetail.class, salesmanIncomeDetail,salesmanApiParamDto.getCurrentPage(),salesmanApiParamDto.getPageSize());
            QueryResult<SalesmanIncomeDetailDto> res = ClassConverUtil.copyQueryResultToDtoQueryResult(salesmanIncomeDetailQueryResult, SalesmanIncomeDetailDto.class, true);
            return res;
        } else {
            return null;
        }


    }

    @Override
    public QueryResult<SalesmanMemberDto> getSalesmanMembers(SalesmanApiParamDto salesmanApiParamDto) throws Exception {

        if (StringUtil.isNotBlank(salesmanApiParamDto.getTicket())) {
            MemberSessionDto memberSessionDto = ApiThreadLocal.getMemberSessionThreadLocal();

            SalesmanBase salesmanBase = new SalesmanBase();
            salesmanBase.setSalesmanWxopenid(memberSessionDto.getOpenid());
            salesmanBase = commonService.findOneEQ(SalesmanBase.class, salesmanBase);

            SalesmanMember salesmanMember = new SalesmanMember();
            salesmanMember.setSalesmanNo(salesmanBase.getSalesmanNo());
            salesmanMember.setLhotelGroupCode(memberSessionDto.getLhotelGroupCode());
            QueryResult<SalesmanMember> salesmanMemberQueryResult = commonService.findAllEQ(SalesmanMember.class, salesmanMember,salesmanApiParamDto.getCurrentPage(),salesmanApiParamDto.getPageSize());
            QueryResult<SalesmanMemberDto> res = ClassConverUtil.copyQueryResultToDtoQueryResult(salesmanMemberQueryResult, SalesmanMemberDto.class, true);

            return res;
        } else {
            return null;
        }
    }

    @Override
    public void saveSalesmanReservation(ReservationParamDto reservationParamDto) throws Exception {
        ReservationBaseDto reservationBaseDto = reservationParamDto.getReservationBase();
        if (StringUtil.isNotBlank(reservationBaseDto.getMemberNo()) || StringUtil.isNotBlank(reservationBaseDto.getOpenid())) {
            L2RCondition l2RCondition = new L2RCondition();
            ArrayList<ConditionDetail> conditionDetailArrayList = new ArrayList<>();
            conditionDetailArrayList.add(new ConditionDetail(SalesmanMember.SalesmanMember_.memberNo.toString(), CriteriaUtil.Operator.EQ, reservationBaseDto.getMemberNo()));
            conditionDetailArrayList.add(new ConditionDetail(SalesmanMember.SalesmanMember_.memberWxopenid.toString(), CriteriaUtil.Operator.EQ, reservationBaseDto.getOpenid()));
            ConditionDetail[] conditionDetails = new ConditionDetail[conditionDetailArrayList.size()];
            for (int i = 0; i < conditionDetailArrayList.size(); i++) {
                conditionDetails[i] = conditionDetailArrayList.get(i);
            }
            l2RCondition.setOrConditions(conditionDetails);
            QueryResult<SalesmanMember> salesmanMemberQueryResult = commonService.findAllByCondition(SalesmanMember.class, l2RCondition);
            SalesmanIncomeDetail salesmanIncomeDetail = new SalesmanIncomeDetail();
            if (null != salesmanMemberQueryResult && salesmanMemberQueryResult.getTotalrecord() > 0) {
                SalesmanMember salesmanMember = salesmanMemberQueryResult.getResultlist().get(0);
                if (null != salesmanMember.getSalesmanNo()) {
                    SalesmanBase salesmanBase = null;
                    SalesmanBase querysb = new SalesmanBase();
                    querysb.setLhotelGroupCode(reservationParamDto.getLhotelGroupCode());
                    querysb.setSalesmanNo(salesmanMember.getSalesmanNo());
                    salesmanBase = commonService.findOneEQ(SalesmanBase.class, querysb);
                    salesmanIncomeDetail.setL2RNo(reservationBaseDto.getL2RNo());
                    salesmanIncomeDetail = commonService.findOneEQ(SalesmanIncomeDetail.class, salesmanIncomeDetail);
                    Integer nights = DateUtil.getDiffDays2(reservationParamDto.getReservationBase().getDep(), reservationParamDto.getReservationBase().getArr());

                    if (salesmanBase != null) {
                        if (null != salesmanIncomeDetail) {
                            salesmanIncomeDetail.setResSta(reservationBaseDto.getResSta());
                            salesmanIncomeDetail.setTotal(salesmanIncomeDetail.getUnit().multiply(new BigDecimal(nights)).multiply(salesmanIncomeDetail.getMultiple()));
                            if ("X".equals(reservationBaseDto.getResSta())) {
                                salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.CANCEL);
                            }
                            commonService.merge(salesmanIncomeDetail);
                        } else {
                            List params = new ArrayList<>();
                            params.add("AWARDNO");
                            String awardNo = commonService.findOneFieldByProcedure("create_No", params);

                            salesmanIncomeDetail = new SalesmanIncomeDetail();
                            salesmanIncomeDetail.setMemberNo(reservationBaseDto.getMemberNo());
                            salesmanIncomeDetail.setFansOpenId(reservationParamDto.getReservationBase().getOpenid());
                            salesmanIncomeDetail.setL2RNo(reservationBaseDto.getL2RNo());
                            salesmanIncomeDetail.setLhotelGroupCode(reservationBaseDto.getLhotelGroupCode());
                            salesmanIncomeDetail.setLhotelCode(reservationBaseDto.getLhotelCode());
                            salesmanIncomeDetail.setNights(new BigDecimal(nights));
                            salesmanIncomeDetail.setAwardNo(awardNo);
                            salesmanIncomeDetail.setAwardType(InComingDetailConstant.AwardType.RESERVATION);
                            salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.INIT);
                            salesmanIncomeDetail.setSalesmanNo(salesmanMember.getSalesmanNo());
                            salesmanIncomeDetail.setSalesmanName(salesmanMember.getSalesmanName());
                            salesmanIncomeDetail.setResSta(reservationBaseDto.getResSta());
                            salesmanIncomeDetail.setMultiple(new BigDecimal(1));
                            salesmanIncomeDetail.setUnit(new BigDecimal(2));
                            salesmanIncomeDetail.setTotal(salesmanIncomeDetail.getUnit().multiply(new BigDecimal(nights)).multiply(salesmanIncomeDetail.getMultiple()));
                            commonService.save(salesmanIncomeDetail);
                        }
                    }
                }

            }
        }
    }

    @Override
    public void awardSalesmanReservation(SalesmanInComeDetailInsideParamDto salesmanInComeDetailInsideParamDto) throws Exception {
        //ReservationBaseDto reservationBaseDto = reservationParamDto.getReservationBaseDto();
        String lhotelGroupCode = salesmanInComeDetailInsideParamDto.getLhotelGroupCode();
        String lhotelCode = salesmanInComeDetailInsideParamDto.getLhotelCode();
        String memberWxOpenid = salesmanInComeDetailInsideParamDto.getOpenid();
        String l2rNo = salesmanInComeDetailInsideParamDto.getL2RNo();
        SalesmanIncomeDetail findDetail = new SalesmanIncomeDetail();
        findDetail.setL2RNo(l2rNo);
        findDetail.setLhotelGroupCode(lhotelGroupCode);
        SalesmanIncomeDetail salesmanIncomeDetail = commonService.findOneEQ(SalesmanIncomeDetail.class, findDetail);

        if (null != salesmanIncomeDetail
                //订单为INIT状态时，为未完结状态，进行同步
                && InComingDetailConstant.AwardSta.INIT.equals(salesmanIncomeDetail.getAwardSta())) {
            //查询联房订单，确认支付方式
            ReservationParamDto rParamDto = new ReservationParamDto();
            rParamDto.setL2rNo(l2rNo);
            rParamDto.setLhotelGroupCode(lhotelGroupCode);
            ReservationDto l2rReservation = reservationsFeignService.getReservation(rParamDto.paramToMap()).getResultInfo();
            L2RAssert.isTrue(l2rReservation == null ,new SysException(SYNC_SALESMAN_AWARD_ERROR," 联房订单查询失败.+[l2rNo]"+l2rNo));
            SalesmanMember salesmanMember = this.findSalesmanMember(lhotelGroupCode, memberWxOpenid);
            L2RAssert.isTrue(null == salesmanMember,
                    new SysException(RodimusSysExceptionEnum.SALESMANMEMBER_NOT_EXIT.getCode(),
                            RodimusSysExceptionEnum.SALESMANMEMBER_NOT_EXIT.getMsg() + "",
                            RodimusSysExceptionEnum.SALESMANMEMBER_NOT_EXIT.getBizType()));
            SalesmanBase salesmanBase = this.findSalesmanBase(lhotelGroupCode, salesmanMember.getSalesmanNo());
            L2RAssert.isTrue(null == salesmanBase,
                    new SysException(RodimusSysExceptionEnum.SALESMAN_NOT_EXIT.getCode(),
                            RodimusSysExceptionEnum.SALESMAN_NOT_EXIT.getMsg() + "",
                            RodimusSysExceptionEnum.SALESMAN_NOT_EXIT.getBizType()));
            //重新计算 PMS 间夜  - -- - - //修改-不重新计算pms间夜
            /*Integer nights = DateUtil.getDiffDays2(salesmanInComeDetailInsideParamDto.getDep(), salesmanInComeDetailInsideParamDto.getArr());
            salesmanIncomeDetail.setNights(new BigDecimal(nights));
            salesmanIncomeDetail.setTotal(salesmanIncomeDetail.getUnit().multiply(new BigDecimal(nights)).multiply(salesmanIncomeDetail.getMultiple()));*/
            salesmanIncomeDetail.setResSta(salesmanInComeDetailInsideParamDto.getResSta());
            salesmanIncomeDetail.setLhotelGroupCode(salesmanInComeDetailInsideParamDto.getLhotelGroupCode());
            salesmanIncomeDetail.setLhotelCode(salesmanBase.getLhotelCode());
           /* if(nights <= 0){
                salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.ERROR);
                commonService.merge(salesmanIncomeDetail);
                return;
            }*/
            //取消单时，直接更新salesmanIncomedetial
            if (ReservationConstant.RESSTA.X.equals(salesmanInComeDetailInsideParamDto.getResSta())) {
                salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.CANCEL);
                commonService.merge(salesmanIncomeDetail);
            }else if (ReservationConstant.RESSTA.O.equals(salesmanInComeDetailInsideParamDto.getResSta())) {
                //离店时确认， 奖励为 CHECKED
                try {
                    //salesMember无效则奖励无效
                    if (new SalemanMemberChecker(salesmanMember).isInvalid() ||
                            //订单类型非预付无效
                            new OrderResTypeChecker(l2rReservation.getReservationBaseDto().getResType()).isInvalid()) {
                        salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.INVALID);
                        commonService.merge(salesmanIncomeDetail);
                    }else{
                        Date notimeArr = DateUtil.parseDateNoTime(salesmanInComeDetailInsideParamDto.getArr());
                        String lockKey = lhotelGroupCode + lhotelCode + memberWxOpenid + notimeArr;
                        Lock lock = syncSalesmanIncomingDetailLock.obtain(lockKey);
                        if(lock.tryLock(10, TimeUnit.SECONDS)){
                            try{
                                boolean hasAwarded = new SalesmanAwardCountChecker(lhotelGroupCode, lhotelCode, notimeArr, memberWxOpenid, commonService).isInvalid();
                                if(hasAwarded){
                                    salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.INVALID);
                                    commonService.merge(salesmanIncomeDetail);
                                }else{
                                    salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.CHECKED);
                                    SalesmanIncomingdetailLogEntity log = new SalesmanIncomingdetailLogEntity();
                                    log.setLhotelGroupCode(lhotelGroupCode);
                                    log.setLhotelCode(lhotelCode);
                                    log.setSalesmanMemberOpenid(memberWxOpenid);
                                    log.setL2RNo(l2rNo);
                                    log.setArrDate(notimeArr);
                                    salesmanRewardsService.salesmanIncomingdetailLog(salesmanIncomeDetail,log);
                                }
                            }finally {
                                lock.unlock();
                            }
                        }else{
                            throw new SysException(SYNC_SALESMAN_AWARD_ERROR,"getLock timeOut,"+"lockKey:"+lockKey);
                        }
                    }
                } finally {
                    //通知salesman fans离店信息
                    notifyFansCheckOut(salesmanBase.getSalesmanWxopenid(), salesmanIncomeDetail);
                }

            } else { //其他状态只做更新,不修改 salesmanIncomeDetail.awardSta
                commonService.merge(salesmanIncomeDetail);
            }
        }
    }


    private SalesmanMember findSalesmanMember(String lhotelGroupCode, String openid) throws Exception {
        L2RAssert.stringBlank(openid,"[openid] is null.分销员奖励订单同步,粉丝openid为空.");
        SalesmanMember findMember = new SalesmanMember();
        findMember.setLhotelGroupCode(lhotelGroupCode);
        findMember.setMemberWxopenid(openid);
        return commonService.findOneEQ(SalesmanMember.class, findMember);
    }

    private SalesmanBase findSalesmanBase(String lhotelGroupCode, String salesmanNo) throws Exception {
        L2RAssert.stringBlank(salesmanNo,"[salesmanNo] is null.分销员查询,分销员salesmanNo为空.");
        SalesmanBase salesmanBase = new SalesmanBase();
        salesmanBase.setLhotelGroupCode(lhotelGroupCode);
        salesmanBase.setSalesmanNo(salesmanNo);
        return commonService.findOneEQ(SalesmanBase.class, salesmanBase);
    }

    /**
     * 奖励有效检查
     * isInvalid 无效 return true
     */
    private interface IncomingdetailChecker {
        boolean isInvalid();
    }

    /**
     * 粉丝有效检查
     */
    private static class SalemanMemberChecker implements IncomingdetailChecker {
        private SalesmanMember salesmanMember;

        public SalemanMemberChecker(SalesmanMember salesmanMember) {
            this.salesmanMember = salesmanMember;
        }

        @Override
        public boolean isInvalid() {
            Date now = new Date();
            return SaleMemberConstant.STA.X.equals(salesmanMember.getSta()) ||
                    now.after(salesmanMember.getAwardEndDatetime()) ||
                    now.before(salesmanMember.getAwardStarDatetime());
        }
    }

    /**
     * 订单支付类型有效性检查
     * 预付奖励
     */
    private static class OrderResTypeChecker implements IncomingdetailChecker {

        private String orderResType;

        public OrderResTypeChecker(String orderResType) {
            this.orderResType = orderResType;
        }

        @Override
        public boolean isInvalid() {
            return !BaseRateplanConstant.RESTYPE.PRE.equals(orderResType);
        }
    }

    /**
     * 粉丝订单奖励次数检查
     */
    private static class SalesmanAwardCountChecker implements IncomingdetailChecker {
        private String lhotelGroupCode;
        private String lhotelCode;
        private Date arrDate;
        private String fansOpenid;
        private ICommonService iCommonService;

        public SalesmanAwardCountChecker(String lhotelGroupCode, String lhotelCode, Date arrDate, String fansOpenid, ICommonService commonService) {
            this.lhotelGroupCode = lhotelGroupCode;
            this.lhotelCode = lhotelCode;
            this.arrDate = arrDate;
            this.iCommonService = commonService;
            this.fansOpenid = fansOpenid;
        }

        @Override
        public boolean isInvalid() {
            SalesmanIncomingdetailLogEntity find = new SalesmanIncomingdetailLogEntity();
            find.setArrDate(arrDate);
            find.setSalesmanMemberOpenid(fansOpenid);
            find.setLhotelCode(lhotelCode);
            find.setLhotelGroupCode(lhotelGroupCode);

            try {
                long count = iCommonService.getCountAllEQ(SalesmanIncomingdetailLogEntity.class, find, null);
                return count > 0;
            } catch (Exception e) {
                throw new SysException(BaseSysExceptionEnum.BASE_FUCATION_OPTION, e);
            }
        }
    }


    private void notifyFansCheckOut(String salesmanOpenid, SalesmanIncomeDetail salesmanIncomeDetail) throws Exception {
        if (StringUtil.isBlank(salesmanOpenid)) {
            throw new SysException(BaseSysExceptionEnum.INVALID_PARA.getCode(), BaseSysExceptionEnum.INVALID_PARA.getMsg() + "salesmanOpenid is null", BaseConstant.SysExceptionConstant.BIZ_TYPE.RODIMUS);
        }
        Map date = new HashMap();
        date.put("openid", salesmanOpenid);
        date.put("l2rNo", salesmanIncomeDetail.getL2RNo());
        date.put("total", salesmanIncomeDetail.getTotal().setScale(2).toString());
        messageFlatPad.send(salesmanIncomeDetail.getLhotelGroupCode(), MsgConstant.CHANNEL.WECHA_CUSTOM_SEND, MsgConstant.TEMPLET_CODE.FANS_CHECK_OUT, date);
    }

    @Override
    public void awardSalesmanMember(SalesmanAwardMemberInsideParamDto salesmanAwardMemberInsideParamDto) throws Exception {
        //ReservationBaseDto reservationBaseDto = reservationParamDto.getReservationBaseDto();\
        if (StringUtil.isBlank(salesmanAwardMemberInsideParamDto.getSalesmanNo())) {
            return;
        }
        SalesmanBase salesmanBase = new SalesmanBase();
        salesmanBase.setLhotelGroupCode(salesmanAwardMemberInsideParamDto.getLhotelGroupCode());
        salesmanBase.setSalesmanNo(salesmanAwardMemberInsideParamDto.getSalesmanNo());
        salesmanBase.setSta(SaleMemberConstant.STA.I);
        salesmanBase = commonService.findOneEQ(SalesmanBase.class, salesmanBase);
        //Todo 根据粉丝
        if (null != salesmanBase) {
            SalesmanMember salesmanMember = new SalesmanMember();
            salesmanMember.setLhotelGroupCode(salesmanBase.getLhotelGroupCode());
            salesmanMember.setLhotelCode(salesmanBase.getLhotelCode());
            salesmanMember.setMemberWxopenid(salesmanAwardMemberInsideParamDto.getOpenId());
            if (null != salesmanAwardMemberInsideParamDto.getWxMemberInfo()) {
                salesmanMember.setMemberWxnickname(salesmanAwardMemberInsideParamDto.getWxMemberInfo().getNickname());
            }
            salesmanMember.setSalesmanName(salesmanBase.getSalesmanName());
            salesmanMember.setSalesmanNo(salesmanBase.getSalesmanNo());
            salesmanMember.setSta(SaleMemberConstant.STA.I);
            salesmanMember.setAwardStarDatetime(new Date());
            salesmanMember.setAwardEndDatetime(DateUtil.addYears(new Date(), 1));
            try {
                commonService.save(salesmanMember);
            } catch (Exception e) {
                LogUtil.logger.error("awardSalesmanMember error:" + e.getMessage());
                salesmanMember.setMemberWxnickname("error_name");
                commonService.save(salesmanMember);
                this.initAndCreateIncomeDetail(salesmanBase, salesmanAwardMemberInsideParamDto.getSalesmanNo(), salesmanAwardMemberInsideParamDto.getOpenId());
                notifyFansAward(salesmanBase.getLhotelGroupCode(), salesmanBase.getSalesmanWxopenid(), salesmanAwardMemberInsideParamDto.getWxMemberInfo().getNickname());
                throw e;
            }
            this.initAndCreateIncomeDetail(salesmanBase, salesmanAwardMemberInsideParamDto.getSalesmanNo(), salesmanAwardMemberInsideParamDto.getOpenId());
            notifyFansAward(salesmanBase.getLhotelGroupCode(), salesmanBase.getSalesmanWxopenid(), salesmanAwardMemberInsideParamDto.getWxMemberInfo().getNickname());
        } else {
            throw new SysException(BaseSysExceptionEnum.INVALID_PARA.getCode(), BaseSysExceptionEnum.INVALID_PARA.getMsg() + "can not find salesmanBase[" + salesmanBase.toString() + "]", BaseSysExceptionEnum.INVALID_PARA.getBizType());
        }
    }

    private void notifyFansAward(String lhotelGroupCode, String salesmanOpenid, String memberNickName) throws Exception {
        Map date = new HashMap();
        date.put("openid", salesmanOpenid);
        date.put("nickname", memberNickName);
        messageFlatPad.send(lhotelGroupCode, MsgConstant.CHANNEL.WECHA_CUSTOM_SEND, MsgConstant.TEMPLET_CODE.SALESMAN_FANS, date);
    }

    private void initAndCreateIncomeDetail(SalesmanBase salesmanBase, String salesmanNo, String fansOpenid) throws Exception {
        List params = new ArrayList<>();
        params.add("AWARDNO");
        String awardNo = commonService.findOneFieldByProcedure("create_No", params);

        SalesmanIncomeDetail salesmanIncomeDetail = new SalesmanIncomeDetail();
        salesmanIncomeDetail.setLhotelGroupCode(salesmanBase.getLhotelGroupCode());
        salesmanIncomeDetail.setLhotelCode(salesmanBase.getLhotelCode());
        salesmanIncomeDetail.setAwardType(InComingDetailConstant.AwardType.MEMBER);
        salesmanIncomeDetail.setAwardSta(InComingDetailConstant.AwardSta.CHECKED);
        salesmanIncomeDetail.setAwardNo(awardNo);
        salesmanIncomeDetail.setUnit(InComingDetailConstant.AwardBaseSum.MEMBER_UNIT);
        salesmanIncomeDetail.setMultiple(BigDecimal.ONE);
        salesmanIncomeDetail.setTotal(salesmanIncomeDetail.getUnit().multiply(salesmanIncomeDetail.getMultiple()));
        salesmanIncomeDetail.setSalesmanNo(salesmanNo);
        salesmanIncomeDetail.setSalesmanName(salesmanBase.getSalesmanName());
        salesmanIncomeDetail.setFansOpenId(fansOpenid);
        commonService.save(salesmanIncomeDetail);
    }

}
